/**
 *    @file       sockettask.cpp
 *
 *    @brief      
 *    @details
 *
 *    @version    1.0
 *    @date       02/13/2014 09:49:57 AM
 *
 *    @author     Theophilus (), wangtf418@gmail.com 
 */
#include "sockettask.h"
#include "server.h"
#include "netprocessthread.h"

atomic_uint64 sockettask::m_cur_taskid;

sockettask::sockettask(csocket *csock, netprocessthread *netthread, const comargs *args /* = NULL */)
	: m_socket(csock), m_netthread(netthread), m_timeout(-1), m_cur_sendmsg(NULL), m_args(NULL)
{
	m_taskid = m_cur_taskid.return_add(1);
	m_last_activetime = server::get()->get_time();
	if (args)
	{
		m_args = args->clone();
	}
	m_netthread->add_sockettask(this);
}

sockettask::~sockettask()
{
	del_from_epoll();
	if (m_socket)
	{
		delete m_socket;
	}
	m_netthread->del_sockettask(this);
}

bf_int_t sockettask::init(bf_time_t timeout /* = SOCKTASK_TIMEOUT */, bf_int_t sock_buflen /* = 102400 */)
{
	if (!m_socket)
	{
		return BF_ERROR;
	}

	m_timeout = timeout;
	m_socket->set_nonblock_opt(true);
	m_socket->set_tcpnodelay_opt(true);

	m_socket->set_recvbuf_opt(sock_buflen);
	m_socket->set_sendbuf_opt(sock_buflen);

	add_to_epoll();
	return BF_OK;
}

bf_int_t sockettask::check_timeout()
{
	if (m_timeout <= 0)
	{
		return BF_FALSE;
	}

	if ((server::get()->get_time() - m_last_activetime) > m_timeout)
	{
		destroy();
		return BF_TRUE;
	}
	return BF_FALSE;
}

bf_int_t sockettask::destroy()
{
	delete this;
	return BF_OK;
}

bf_int_t sockettask::put_send_packet(bf_char_t *buf, bf_size_t buflen)
{
	if (!buf || buflen == 0)
	{
		return BF_ERROR;
	}
	send_message *sendmsg = new send_message(buf, buflen);
	bf_bool_t ifemtpy = m_send_list.empty();
	m_send_list.push_back(sendmsg);
	if (ifemtpy)
	{
		modify_epoll((BF_EPOLL_IN | BF_EPOLL_OUT));
	}
	return BF_OK;
}

bf_int_t sockettask::add_to_epoll(bf_int_t events /* = BF_EPOLL_IN */)
{
	bf_int_t events_tmp = BF_EPOLL_ERR | BF_EPOLL_HUP | events;
	m_netthread->get_epoll().add(m_socket->get_socket(), events_tmp, this);
	return BF_OK;
}

bf_int_t sockettask::del_from_epoll()
{
	if (!m_socket)
	{
		return BF_OK;
	}
	m_netthread->get_epoll().del(m_socket->get_socket(), this);
	return BF_OK;
}

bf_int_t sockettask::modify_epoll(bf_int_t events)
{
	bf_int_t events_tmp = BF_EPOLL_ERR | BF_EPOLL_HUP | events;
	m_netthread->get_epoll().modify(m_socket->get_socket(), events_tmp, this);
	return BF_OK;
}


